package vn.edu.saigontech.ncms.web.teacher;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;

import vn.edu.saigontech.ncms.model.enumeration.Campus;
import vn.edu.saigontech.ncms.model.enumeration.Gender;
import vn.edu.saigontech.ncms.model.enumeration.Nationality;
import vn.edu.saigontech.ncms.model.enumeration.TeacherType;
import vn.edu.saigontech.ncms.model.info.Teacher;
import vn.edu.saigontech.ncms.service.OfferingService;
import vn.edu.saigontech.ncms.service.TeacherService;
import vn.edu.saigontech.ncms.util.DateUtil;
import vn.edu.saigontech.ncms.util.I18n;
import vn.edu.saigontech.ncms.web.BaseAction;


@SuppressWarnings("serial")
public class TeacherAction extends BaseAction {
	
	private Long id;
	private String firstName;
	private String midName;
	private String lastName;
	private String dateOfBirth;
	private String teacherType;
	private String gender;
	private String nationality;
	private String campus;
	private String email;
	private String phoneNumber;
	private Boolean active;
	private String comment;
	
	private String fromDate;
	private String toDate;
	
	private Collection<Teacher> teachers;
	
	public String showAdd() {
		REQUEST().setAttribute("teacherTypes", TeacherType.values());
		REQUEST().setAttribute("nationalities", Nationality.values());
		REQUEST().setAttribute("campuses", Campus.values());
		return SUCCESS;
	}
	
	public String add() {
		Teacher teacher = new Teacher();
		teacher.setFirstName(this.firstName);
		teacher.setMidName(this.midName);
		teacher.setLastName(this.lastName);
		teacher.setDateOfBirth(DateUtil.fromString(this.dateOfBirth, this.i18n("format.date")));
		teacher.setTeacherType(TeacherType.create(this.teacherType));
		teacher.setGender(Gender.create(this.gender));
		teacher.setNationality(Nationality.create(this.nationality));
		teacher.setCampus(Campus.create(this.campus));
		teacher.setEmail(this.email);
		teacher.setPhoneNumber(this.phoneNumber);
		teacher.setComment(this.comment);
		teacher = TeacherService.INSTANCE.persist(teacher);
		this.id = teacher.getId();
		
		this.addLoggingDetail(BaseAction.ADD, "logging.teacher.add", teacher.getFullName());
		return SUCCESS;
	}
	
	public String info() {
		REQUEST().setAttribute("teacher", TeacherService.INSTANCE.findById(this.id));
		return SUCCESS;
	}
	
	public String showEdit() {
		REQUEST().setAttribute("nationalities", Nationality.values());
		REQUEST().setAttribute("campuses", Campus.values());
		REQUEST().setAttribute("teacherTypes", TeacherType.values());
		REQUEST().setAttribute("teacher", TeacherService.INSTANCE.findById(this.id));
		return SUCCESS;
	}
	
	public String edit() {
		Teacher teacher = TeacherService.INSTANCE.findById(this.id);
		teacher.setFirstName(this.firstName);
		teacher.setMidName(this.midName);
		teacher.setLastName(this.lastName);
		teacher.setDateOfBirth(DateUtil.fromString(this.dateOfBirth, this.i18n("format.date")));
		teacher.setTeacherType(TeacherType.create(this.teacherType));
		teacher.setGender(Gender.create(this.gender));
		teacher.setNationality(Nationality.create(this.nationality));
		teacher.setCampus(Campus.create(this.campus));
		teacher.setEmail(this.email);
		teacher.setPhoneNumber(this.phoneNumber);
		teacher.setComment(this.comment);
		teacher.setActive(Boolean.TRUE.equals(this.active)? Boolean.TRUE : Boolean.FALSE);
		TeacherService.INSTANCE.persist(teacher);
		
		this.addLoggingDetail(BaseAction.EDIT, "logging.teacher.edit", teacher.getFullName());
		return SUCCESS;
	}
	
	public String showSearch() {
		REQUEST().setAttribute("teacherTypes", TeacherType.values());
		REQUEST().setAttribute("nationalities", Nationality.values());
		REQUEST().setAttribute("campuses", Campus.values());
		return SUCCESS;
	}
	
	public String search() {
		this.teachers = TeacherService.INSTANCE.find(
			this.firstName,
			this.midName,
			this.lastName,
			DateUtil.fromString(this.dateOfBirth, this.i18n("format.date")),
			TeacherType.create(this.teacherType),
			Gender.create(this.gender),
			Nationality.create(this.nationality),
			Campus.create(this.campus),
			this.email, 
			this.phoneNumber,
			DateUtil.fromString(this.fromDate, this.i18n("format.date")),
			DateUtil.fromString(this.toDate, this.i18n("format.date")),
			this.active,
			this.comment
		);
		this.addLoggingDetail(BaseAction.SEARCH, "logging.teacher.search");
		SESSION().setAttribute("teacherss", teachers);
		return SUCCESS;
	}
	
	public String report() {
		this.teachers = TeacherService.INSTANCE.find(
				this.firstName,
				this.midName,
				this.lastName,
				null,
				null,
				Gender.create(this.gender),
				Nationality.create(this.nationality),
				Campus.create(this.campus),
				this.email, 
				this.phoneNumber,
				DateUtil.fromString(this.fromDate, this.i18n("format.date")),
				DateUtil.fromString(this.toDate, this.i18n("format.date")),
				this.active,
				this.comment
	    );
		RESPONSE().setContentType("application/vnd.ms-excel");
		RESPONSE().setHeader("Content-disposition","attachment; filename=\""+ "InstructorsInformation.xls\"");
		try {
			HSSFWorkbook workbook = new HSSFWorkbook();
			HSSFSheet sheet = workbook.createSheet("Instructors");
			
			HSSFFont font18 = this.makeFont(workbook, "Times New Roman", 18, true);
			HSSFFont font12 = this.makeFont(workbook, "Times New Roman", 12, true);
			HSSFFont font11 = this.makeFont(workbook, "Times New Roman", 11, false);
			
			HSSFCellStyle style1 = this.makeCellStyle(workbook, HSSFCellStyle.ALIGN_CENTER, HSSFCellStyle.VERTICAL_CENTER, font12);
			HSSFCellStyle style3 = this.makeCellStyle(workbook, HSSFCellStyle.ALIGN_CENTER, HSSFCellStyle.VERTICAL_CENTER, font11);
			HSSFCellStyle style4 = this.makeCellStyle(workbook, HSSFCellStyle.ALIGN_LEFT, HSSFCellStyle.VERTICAL_CENTER, font11);
			
			HSSFRow row = sheet.createRow(0);
			row.setHeightInPoints(30);
			HSSFCell cell = row.createCell(0, HSSFCell.CELL_TYPE_STRING);
			cell.setCellStyle(this.makeCellStyle(workbook, HSSFCellStyle.ALIGN_CENTER, HSSFCellStyle.VERTICAL_CENTER, font18));
			cell.setCellValue(new HSSFRichTextString("INSTRUCTORS INFORMATION"));
			sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 5));
			
			row = sheet.createRow(2);
			this.makeColumnLabel(workbook, sheet, row, 0, "No.", 2000, style1);
			this.makeColumnLabel(workbook, sheet, row, 1, "Full name", 10000, style1);
			this.makeColumnLabel(workbook, sheet, row, 2, "Gender", 2500, style1);
			this.makeColumnLabel(workbook, sheet, row, 3, "Phone No.", 7000, style1);
			this.makeColumnLabel(workbook, sheet, row, 4, "E-mail", 8000, style1);
			this.makeColumnLabel(workbook, sheet, row, 5, "Campus", 3500, style1);
			
			List<Teacher> list = new ArrayList<Teacher>(teachers);
			I18n i18n = new I18n();
			int r = 3;
			for(int i = 0; i < list.size(); i++) {
				Teacher teacher = list.get(i);
				row = sheet.createRow(r);
				// No.
				cell = row.createCell(0, HSSFCell.CELL_TYPE_NUMERIC);
				cell.setCellValue(i + 1);
				cell.setCellStyle(style3);
				
				// Full name
				cell = row.createCell(1, HSSFCell.CELL_TYPE_STRING);
				cell.setCellValue(new HSSFRichTextString(i18n.getMessage(teacher.getTitle().getKey()) + ". " + teacher.getFullName().toUpperCase()));
				cell.setCellStyle(style4);
				
				// Gender
				cell = row.createCell(2, HSSFCell.CELL_TYPE_STRING);
				cell.setCellValue(new HSSFRichTextString(i18n.getMessage(teacher.getGender().getKey())));
				cell.setCellStyle(style3);
				
				// Phone No.
				cell = row.createCell(3, HSSFCell.CELL_TYPE_STRING);
				cell.setCellValue(new HSSFRichTextString(teacher.getPhoneNumber()));
				cell.setCellStyle(style4);
				
				// E-mail
				cell = row.createCell(4, HSSFCell.CELL_TYPE_STRING);
				cell.setCellValue(new HSSFRichTextString(teacher.getEmail()));
				cell.setCellStyle(style4);
				
				// Campus
				cell = row.createCell(5, HSSFCell.CELL_TYPE_STRING);
				cell.setCellValue(new HSSFRichTextString(""));
				cell.setCellStyle(style3);
				
				r++;
			}
			workbook.write(RESPONSE().getOutputStream());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		this.addLoggingDetail(BaseAction.REPORT, "logging.teacher.report");
		return NONE;
	}
	
	public String delete() {
		Teacher teacher = TeacherService.INSTANCE.findById(this.id);
		String name = teacher.getFullName();
		if(TeacherService.INSTANCE.deleteById(this.id)) {
			this.setKeyMessage("confirm.deleteSuccessfully", "teacher");
		}
		else {
			this.setKeyMessage("confirm.deleteUnsuccessfully", "teacher");
		}
		
		this.addLoggingDetail(BaseAction.DELETE, "logging.teacher.delete", name);
		return SUCCESS;
	}
	
	public String listOffering() {
		REQUEST().setAttribute("teacher", TeacherService.INSTANCE.findById(this.id));
		REQUEST().setAttribute("offerings", OfferingService.INSTANCE.findByTeacherIdSortByStartDate(this.id));
		return SUCCESS;
	}
	
	private void makeColumnLabel(HSSFWorkbook workbook, HSSFSheet sheet, HSSFRow row, int index, String label, int width, HSSFCellStyle style) {
		HSSFCell cell = row.createCell(index, HSSFCell.CELL_TYPE_STRING);
		cell.setCellStyle(style);
		cell.setCellValue(new HSSFRichTextString(label));
		sheet.setColumnWidth(index, (short)width);
	}
	
	private HSSFFont makeFont(HSSFWorkbook workbook, String name, int size, boolean isBold) {
		HSSFFont font = workbook.createFont();
		font.setFontHeightInPoints((short)size);
		font.setFontName(name);
		if(isBold) {
			font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		}
		return font;
	}
	
	private HSSFCellStyle makeCellStyle(HSSFWorkbook workbook, int halign, int valign, HSSFFont font) {
		HSSFCellStyle style = workbook.createCellStyle();
		style.setAlignment((short) halign);
		style.setVerticalAlignment((short) valign);
		style.setWrapText(true);
		style.setFont(font);
		return style;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getMidName() {
		return midName;
	}

	public void setMidName(String midName) {
		this.midName = midName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Boolean getActive() {
		return active;
	}

	public void setActive(Boolean active) {
		this.active = active;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getNationality() {
		return nationality;
	}

	public void setNationality(String nationality) {
		this.nationality = nationality;
	}

	public String getCampus() {
		return campus;
	}

	public void setCampus(String campus) {
		this.campus = campus;
	}

	public Collection<Teacher> getTeachers() {
		return teachers;
	}

	public void setTeachers(Collection<Teacher> teachers) {
		this.teachers = teachers;
	}

	public String getTeacherType() {
		return teacherType;
	}

	public void setTeacherType(String teacherType) {
		this.teacherType = teacherType;
	}

	public String getFromDate() {
		return fromDate;
	}

	public void setFromDate(String fromDate) {
		this.fromDate = fromDate;
	}

	public String getToDate() {
		return toDate;
	}

	public void setToDate(String toDate) {
		this.toDate = toDate;
	}

	public String getDateOfBirth() {
		return dateOfBirth;
	}

	public void setDateOfBirth(String dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}
}